require("SOD/tools/dialogs/dialog")

module SOD

  class String
    def is_i?
       !!(self =~ /^[-+]?[0-9]+$/)
    end
  end

  class StructureGeneratorDialog < Dialog
    
    attr_reader :webDialog, :sgor, :bar_ui, :web_ui
    
    def initialize(interface, title = "Default", scrollbars = true, w = 660, h = 780, l = 150, t = 150)
      @interface = interface
      @title = title
      @scrollbars = scrollbars
      @key = "StructureGeneratorDialog" #registry key that stores dialog preferences (size, position)
      @width = w
      @height = h
      @left = l
      @top = t
      @resizable = true
      @webDialog = UI::WebDialog.new(@title, @scrollbars, @key, \
        @width, @height, @left, @top, @resizable)
      set_file("StructureGenerator.html")
        # set_file("NoSelection.html")

      @bars = Plugin.sgdata.bars
      @slt_bars = Plugin.sgdata.slt_bars
      # @active_bar = Plugin.sgdata.active_bar
      @active_bar = nil
      @default_bar = Plugin.sgdata.default_bar

      init_bar_ui
      init_web_ui
      add_callbacks

      Plugin.sgdata.dialog = self
      update
    end

    def show
      if @webDialog.visible?
         # @webDialog.bring_to_front
      else
         @webDialog.show
      end
    end

    def set_file(file)
      @path = Sketchup.find_support_file("SOD/tools/dialogs/html/" \
        + file, "Plugins")
      @webDialog.set_file(@path, nil)
      puts "set_file: ", @path.to_s
    end

    def init_bar_ui
      @bar_ui = Hash.new
      @bar_ui[:fp_wdt] = :Value
      @bar_ui[:fp_lng] = :Value
      @bar_ui[:co_hgh] = :Slider
      @bar_ui[:ps_col] = :Slider# position of inner columns
      @bar_ui[:p_muta] = :Slider # mutation probability
      @bar_ui[:p_crss] = :Slider # corssover probability
      @bar_ui[:p_size] = :Slider # population size
      @bar_ui[:nof_gn] = :Slider # nof generations
      @bar_ui[:clzn_r] = :RangeSlider# column zone range low bound
      @bar_ui[:clsp_r] = :RangeSlider # column spacing range heigh bound
      @bar_ui[:n_rows] = :MultiSelect # number of rows
      @bar_ui[:dircts] = :MultiSelect # possible primary beam directions
      @bar_ui[:fd_wdt] = :MultiSelect # facade width
      @bar_ui[:cl_sps] = :MultiSelect # possible column spacing
    end
    def init_web_ui
      @web_ui = Hash.new
      @web_ui[:set_open_div] = false # configurations setting is open?
      @web_ui[:ga_set_open_div] = false # configurations setting is open?
    end
    
    def add_callbacks
      super #-> now contains callbacks for onLaod, onCancel and onClose -> Dialog is not updated when closed any more
      @webDialog.add_action_callback("on_change_var") {
       |d, p| on_change_var(d, p) }
      @webDialog.add_action_callback("on_change_ui") {
        |d, p| on_change_ui(d, p) }
      @webDialog.add_action_callback("update_time_message") {
       |d, p| update_time_message(d, p) }
      @webDialog.add_action_callback("update_configurations") {
       |d, p| update_configurations(d, p) }
      @webDialog.add_action_callback("read_database") {
       |d, p| read_database(d, p) }
      @webDialog.add_action_callback("run_generator") {
       |d, p| run_generator(d, p) }
      @webDialog.add_action_callback("show_structure") {
       |d, p| show_structure(d, p) }
      @webDialog.add_action_callback("log_rb") {
       |d, p| puts p }
      @webDialog.add_action_callback("default_configuration") {
       |d, p| default_configuration(d, p) }
      @webDialog.add_action_callback("draw_in_tekla") {
       |d, p| draw_in_tekla(d, p) }
    end
    
    #def onLoad -> moved to SuperClass <Dialog>
    #  update
    #end
    
    def update

      get_selected_bar

      puts self.to_s, " is updated"

      if @sodBar.nil?
        @active_bar = nil
        # set_file("NoSelection.html")
      else
        @sodBar.update_SGhash
        @active_bar = @sodBar.sgHash.bar_hash
        # set_file("StructureGenerator.html")
        update_configurations(nil, nil)
      end

      # Plugin.sgdata.update_bar_by_model
    end

    def update_time_message(d, p)

    end
    

    def on_change_var(d, p)
      # puts p
      args = p.split(",")
      key = args[0].to_sym 
      case @bar_ui[key]
        when :Slider
          val = args[1]
          val = !!(val =~ /^[-+]?[0-9]+$/) ? val.to_i : val.to_f
          @active_bar[key] = val
          @slt_bars.each{ |idx| @bars[idx][key] = val }
        when :RangeSlider
          all_int = true
          args[1..2].each{|e| all_int = false if !(e =~ /^[-+]?[0-9]+$/) }
          v1 = all_int ? args[1].to_i : args[1].to_f
          v2 = all_int ? args[2].to_i : args[2].to_f
          @active_bar[key] = [v1, v2] 
          @slt_bars.each{ |idx| 
            @bars[idx][key] = [v1, v2]
          }
        when :MultiSelect
          args.delete_at(0)
          if not ( args.length == 1 && ( args[0] == "null" || args[0] == "") )
            all_int = true
            args.each{|e| all_int = false if !(e =~ /^[-+]?[0-9]+$/) }
          # @active_bar[key] = args.map! { |e| all_int ? e.to_i : e.to_f }
            if all_int
              @active_bar[key] = args.map { |e| e.to_i }
            else
              @active_bar[key] = args.map { |e| e.to_f }
            end  
            @slt_bars.each{ |idx| 
              @bars[idx][key] = @active_bar[key]
            }    
          else
            @active_bar[key] = []
            @slt_bars.each{ |idx| @bars[idx][key] = [] }
          end
        when :Select
          args.delete_at(0)
          if not ( args.length == 1 && ( args[0] == "null" || args[0] == "") )
            val = args[1]
            val = !!(val =~ /^[-+]?[0-9]+$/) ? val.to_i : val.to_f
            @active_bar[key] = val
            @slt_bars.each{ |idx| @bars[idx][key] = val }
          else
            @active_bar[key] = []
            @slt_bars.each{ |idx| @bars[idx][key] = [] }
          end
        else
      end
    end
    # def on_change_var(d, p)
    #   puts p
    #   args = p.split(",")
    #   key = args[0].to_sym 
    #   case args.size
    #   when 1
    #   when 2
    #     val = args[1]
    #     if val != "null"
    #       val = !!(val =~ /^[-+]?[0-9]+$/) ? val.to_i : val.to_f
    #       @active_bar[key] = val
    #       @slt_bars.each{ |idx| @bars[idx][key] = val }
    #     else
    #       if @default_bar[key].is_a? Array
    #         @active_bar[key] = []
    #         @slt_bars.each{ |idx| @bars[idx][key] = [] }
    #       else
    #         @active_bar[key] = nil
    #         @slt_bars.each{ |idx| @bars[idx][key] = nil }
    #       end
    #     end
    #   when 3
    #     all_int = true
    #     args[1..2].each{|e| all_int = false if !(e =~ /^[-+]?[0-9]+$/) }
    #     v1 = all_int ? args[1].to_i : args[1].to_f
    #     v2 = all_int ? args[2].to_i : args[2].to_f
    #     @active_bar[key] = [v1, v2] 
    #     @slt_bars.each{ |idx| 
    #       @bars[idx][key] = [v1, v2]
    #     }
    #   else
    #     args.delete_at(0)
    #     all_int = true
    #     args.each{|e| all_int = false if !(e =~ /^[-+]?[0-9]+$/) }
    #     # @active_bar[key] = args.map! { |e| all_int ? e.to_i : e.to_f }
    #     if all_int
    #       @active_bar[key] = args.map { |e| e.to_i }
    #     else
    #       @active_bar[key] = args.map { |e| e.to_f }
    #     end  
    #     @slt_bars.each{ |idx| 
    #       @bars[idx][key] = @active_bar[key]
    #     }    
    #   end
    #     # puts @active_bar[key]
    # end
    
    def on_change_ui(d, p)
      # puts p
      args = p.split(",")
      key = args[0].to_sym 
      @web_ui[key] = args[1]
    end

    # def default_configuration(d, p)
    #   # @active_bar[:fp_wdt] = 12.5
    #   # @active_bar[:fp_lng] = 28.8
    #   @default_bar.each{ |key|
    #     @active_bar[key] = @default_bar[key].nil? ? @default_bar[key] : @default_bar[key].clone
    #   }
    #   puts @active_bar.each{|k,v| 
    #     puts k
    #     puts v
    #   }
    #   update
    # end

    def update_configurations(d, p)
      return if not @active_bar
      puts @active_bar.to_s
      # @active_bar[:fp_wdt] = 13.0
      # @active_bar[:fp_lng] = 28.8
      @bar_ui.each{|key, uitype|
          if uitype == :Value
            js_command = "fromRb_" + "Set" + uitype.to_s + \
            "(\"#"+ key.to_s + uitype.to_s + "\",\"" + Array(@active_bar[key]).join(",")+"\")"
            @webDialog.execute_script(js_command)
            puts js_command
          end
      }
      @bar_ui.each{|key, uitype|
          if uitype == :Slider
            js_command = "fromRb_" + "Set" + uitype.to_s + \
            "(\"#"+ key.to_s + uitype.to_s + "\",\"" + Array(@active_bar[key]).join(",")+"\")"
            @webDialog.execute_script(js_command)
            puts js_command
          end
      }
      @bar_ui.each{|key, uitype|
          if uitype == :RangeSlider
            js_command = "fromRb_" + "Set" + uitype.to_s + \
            "(\"#"+ key.to_s + uitype.to_s + "\",\"" + Array(@active_bar[key]).join(",")+"\")"
            @webDialog.execute_script(js_command)
            puts js_command
          end
      }
      @bar_ui.each{|key, uitype|
          if uitype == :MultiSelect
            js_command = "fromRb_" + "Set" + uitype.to_s + \
            "(\"#"+ key.to_s + uitype.to_s + "\",\"" + Array(@active_bar[key]).join(",")+"\")"
            @webDialog.execute_script(js_command)
            puts js_command
          end
      }
      @web_ui.each{ |key, arg|
        @webDialog.execute_script("fromRb_SetWebUi(\""+key.to_s+"\","+arg.to_s+")")
      }
    end

    def read_database(d,p)
      Plugin.sgdata.read_database
    end
    def run_generator(d,p)
      puts "run_generator: "
      Plugin.sgdata.run_generator(@active_bar)
    end
    def show_structure(d,p)
      Plugin.model.drawConstruction
    end
    def draw_in_tekla(d,p)
      Plugin.sgdata.draw_in_tekla(@active_bar)
    end

    def updata_sg_message(osg_message)
        js_command = "fromRb_UpdateTimeMessage(\""+ osg_message + "\")"
        @webDialog.execute_script(js_command)
    end
  end
end


